package com.parking.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.parking.common.core.model.PageInfo;
import com.parking.common.core.model.StateData;
import com.parking.common.core.util.BeanUtilCommon;
import com.parking.common.core.util.DateUtil;
import com.parking.order.client.dto.CertifiedInfoDto;
import com.parking.order.dao.EntranceInfoDao;
import com.parking.order.dao.OrderInfoDao;
import com.parking.order.model.EntranceInfo;
import com.parking.order.model.OrderInfo;
import com.parking.order.model.OrderOvertime;
import com.parking.order.dao.OrderOvertimeDao;
import com.parking.order.model.dto.OvertimeCertifiedDto;
import com.parking.order.model.dto.OvertimeDto;
import com.parking.order.model.dto.OvertimePlatformDto;
import com.parking.order.model.exception.OrderException;
import com.parking.order.model.exception.OrderExceptionCode;
import com.parking.order.model.param.FindOvertimeByOrderNumParam;
import com.parking.order.model.param.FindOvertimeParam;
import com.parking.order.service.IEntranceInfoService;
import com.parking.order.service.IOrderOvertimeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.parking.order.util.BasicInfoUtil;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 吴彦祖
 * @since 2023年11月28日
 */
@Service
public class OrderOvertimeServiceImpl extends ServiceImpl<OrderOvertimeDao, OrderOvertime> implements IOrderOvertimeService {
    /**
     * 订单信息数据层
     * */
    @Autowired
    private OrderInfoDao orderInfoDao;
    /**
     * 进出口信息数据层
     * */
    @Autowired
    private EntranceInfoDao entranceInfoDao;
    /**
     * 其他模块调用工具类
     * */
    @Autowired
    private BasicInfoUtil basicInfoUtil;
    /**
     * 进出口信息服务层
     * */
    @Autowired
    private IEntranceInfoService entranceInfoService;
    /**
     * 超时订单数据层
     * */
    @Autowired
    private OrderOvertimeDao orderOvertimeDao;


    /**
     * 出租客根据订单编号查询超时订单
     * 参数 出租客Id rentersId
     *      用户Id  userId
     *      订单编号 orderInfoNum
     * 返回  开始时间 startTime
     *      结束时间 endTime
     *      持续小时 enduHour
     *      支付价格 payPrice
     *      支付状态 payState 0未支付 1已支付
     * */
    @Override
    public OvertimeDto findOvertimeByOrderNum(FindOvertimeByOrderNumParam param) throws Exception {
        entranceInfoService.checkUserPlatformRentersForOrderInfoNum(param.getUserId(),null,param.getRentersId(),param.getOrderInfoNum());

        OrderOvertime overtime = orderOvertimeDao.selectOne(new QueryWrapper<OrderOvertime>().eq("order_info_num", param.getOrderInfoNum()));
        if(overtime==null) throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_ORDER_NO_OVERTIME_INFO);
        OvertimeDto dto = BeanUtil.toBean(overtime, OvertimeDto.class);

        String startTime = DateUtil.localDateTimeToString(overtime.getStartTime());
        String endTime = DateUtil.localDateTimeToString(overtime.getEndTime());
        dto.setTime(startTime+"-"+endTime);

        String payState = "";
        if(Objects.equals(overtime.getPayState(), StateData.ORDER_OVERTIME_NOT_PAY)) payState = "未支付";
        if(Objects.equals(overtime.getPayState(), StateData.ORDER_OVERTIME_PAID)) payState = "已支付";
        dto.setPayState(payState);

        return dto;
    }

    /**
     * 平台分页查询超时订单
     * 参数 页数 pageNum
     *     每页大小 pageSize
     *     订单编号 orderInfoNum
     *     用户信息Id userInfoId
     *     物业信息Id certifiedInfoId
     *     车位信息Id  stallInfoId
     *     支付状态 payState 0未支付 1已支付
     *     开始日期 startDate
     *     结束日期 endDate
     *     平台Id platformId
     *     物业Id certifiedId
     *
     * 返回 订单编号 orderInfoNum
     *      用户信息Id userInfoId
     *      用户名称 userInfoName
     *      车牌号 userCarPlate
     *      车位信息Id stallInfoId
     *      车位号 stallInfo
     *      物业信息Id certifiedInfoId
     *      物业名称 certifiedInfoName
     *      开始时间 startTime
     *      结束时间 endTime
     *      支付时间 payTime
     *      持续小时 enduHour
     *      支付状态 payState 未支付 已支付
     *      支付价格 payPrice
     * */
    @Override
    public PageInfo findOvertime(FindOvertimeParam param) throws Exception {
        boolean isPlatformId = param.getPlatformId()!=null;
        boolean isCertifiedId = param.getCertifiedId()!=null;
        if(isPlatformId) basicInfoUtil.getPlatform(param.getPlatformId());
        if(isCertifiedId) param.setCertifiedInfoId(basicInfoUtil.getCertifiedAccount(param.getCertifiedId()).getCertifiedInfoId());

        // orderInfoNum userInfoName certifiedInfoName stallInfo payState startDate endDate
        boolean isOrderInfoNum = param.getOrderInfoNum()!=null;
        boolean isUserInfoId = param.getUserInfoId()!=null;
        boolean isCertifiedInfoId = param.getCertifiedInfoId()!=null;
        boolean isStallInfoId = param.getStallInfoId()!=null;
        boolean isStallInfo = param.getStallInfo()!=null&&!param.getStallInfo().equals("");
        boolean isPayState = param.getPayState()!=null;
        boolean isStartTime = param.getStartTime()!=null;
        boolean isEndTime = param.getEndTime()!=null;

        if(isStartTime&&isEndTime){
            if(param.getEndTime().isBefore(param.getStartTime())) throw new OrderException(OrderExceptionCode.ORDER_EXCEPTION_CODE_START_NOT_BEFORE_END);
        }

        Page<OrderOvertime> page = new Page<>(param.getPageNum(), param.getPageSize());
        QueryWrapper<OrderOvertime> wrapper = new QueryWrapper<>();
        // 1.添加判断条件
        if(isOrderInfoNum) wrapper.eq("order_info_num",param.getOrderInfoNum());
        if(isUserInfoId) wrapper.eq("user_info_id",param.getUserInfoId());
        if(isCertifiedInfoId) wrapper.eq("certified_info_id",param.getCertifiedInfoId());
        if(isStallInfo) {
            // stallInfo & certifiedInfoId 对应唯一 stallInfoId
            EntranceInfo someEntrance = entranceInfoDao.selectOne(new QueryWrapper<EntranceInfo>().eq("stall_info",param.getStallInfo()).eq("certified_info_id",param.getCertifiedInfoId()).orderByDesc("update_time").last("LIMIT 1"));
            if(someEntrance==null){
                wrapper.eq("stall_info_id",-1);
            }else wrapper.eq("stall_info_id",someEntrance.getStallInfoId());
        }
        if(isStallInfoId) wrapper.eq("stall_info_id",param.getStallInfoId());
        if(isPayState) wrapper.eq("pay_state",param.getPayState());
        if(isStartTime) wrapper.ge("update_time",param.getStartTime());
        if(isEndTime) wrapper.le("start_time",param.getEndTime());

        wrapper.orderByDesc("update_time");
        orderOvertimeDao.selectPage(page,wrapper);

        ArrayList<OvertimePlatformDto> dtos = new ArrayList<>();
        for (OrderOvertime overtime : page.getRecords()) {
            OvertimePlatformDto dto = BeanUtil.toBean(overtime,OvertimePlatformDto.class);
            // 2.组装每一个dto
            // certifiedInfoName userInfoName stallInfo userCarPlate payState
            CertifiedInfoDto certifiedInfo = basicInfoUtil.getCertifiedInfo(dto.getCertifiedInfoId());
            dto.setCertifiedInfoName(certifiedInfo.getCertifiedInfoName());
            dto.setCertifiedInfoTel(certifiedInfo.getCertifiedInfoTel());
            dto.setCertifiedInfoAddress(certifiedInfo.getCertifiedInfoAddress());
            dto.setUserInfoName(basicInfoUtil.getUserInfo(dto.getUserInfoId()).getUserInfoName());
            OrderInfo order = orderInfoDao.selectOne(new QueryWrapper<OrderInfo>().eq("order_info_num", dto.getOrderInfoNum()));
            dto.setStallInfo(order.getStallInfo());
            dto.setUserCarPlate(order.getUserCarPlate());
            String payState = null;
            if(Objects.equals(overtime.getPayState(), StateData.ORDER_OVERTIME_NOT_PAY)) payState = "未支付";
            if(Objects.equals(overtime.getPayState(), StateData.ORDER_OVERTIME_PAID)) payState = "已支付";
            dto.setPayState(payState);
            dtos.add(dto);
        }
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setTotal(page.getTotal());
        if(isPlatformId) pageInfo.setRecords(dtos);
        if(isCertifiedId) pageInfo.setRecords(BeanUtilCommon.BeanToList(dtos, OvertimeCertifiedDto.class));
        return pageInfo;
    }


}
